package com.hzw.saas.web.app.group.aspect;

import java.util.Objects;

import com.hzw.saas.api.group.IGroupService;
import com.hzw.saas.common.config.util.AssertUtil;
import com.hzw.saas.common.security.utils.SecurityUtils;
import com.hzw.saas.common.util.SpringELUtils;
import com.hzw.saas.service.group.mapper.GroupMemberMapper;
import com.hzw.saas.service.group.model.GroupMember;
import com.hzw.saas.web.app.group.annotation.GroupOperation;
import com.hzw.saas.web.app.group.annotation.MemberOperation;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

/**
 * <p>
 * 控制权限
 * </p>
 *
 * @author sonam
 * @since 2020-12-23
 */
@Aspect
@Component
@Slf4j
@AllArgsConstructor
public class GroupAspect {

    private final IGroupService groupService;

    private final GroupMemberMapper groupMemberMapper;

    /**
     * @param joinPoint
     * @throws Throwable
     */
    @Before("@annotation(memberOperation)")
    @SneakyThrows
    public void memberBefore(JoinPoint joinPoint, MemberOperation memberOperation) {
        String memberId = SpringELUtils.getSpelValue(joinPoint, memberOperation.memberId(), String.class);

        // 判断当前用户是否可以设置该成员的权限
        GroupMember groupMember = groupMemberMapper.selectById(memberId);
        AssertUtil.assertThrow("成员不存在，请重试", Objects.isNull(groupMember));

        String userId = SecurityUtils.getUser().getUserId();
        AssertUtil.assertThrow(memberOperation.error(),
            HttpStatus.FORBIDDEN,
            !groupService.tryGetGroup(userId, groupMember.getGroupId()));
    }

    @Before("@annotation(groupOperation)")
    @SneakyThrows
    public void groupBefore(JoinPoint joinPoint, GroupOperation groupOperation) {
        String groupId = SpringELUtils.getSpelValue(joinPoint, groupOperation.groupId(), String.class);

        AssertUtil.assertThrow(groupOperation.errorMsg(),
            groupOperation.status(),
            !groupService.tryGetGroup(SecurityUtils.getUser().getUserId(), groupId));
    }

}
